using Microsoft.Extensions.Configuration;
using Serilog;
using Serilog.Events;
using Serilog.Sinks.PostgreSQL;

namespace AdminSG3L.Infrastructure;

/// <summary>
/// SerilogConfiguration 负责日志系统的初始化和配置。
/// 日志参数全部从IConfiguration（如appsettings.json）读取，支持灵活调整和环境切换。
/// 如需扩展日志输出目标（如文件、Elasticsearch等），可在此类中统一配置。
/// </summary>
public static class SerilogConfiguration
{
    /// <summary>
    /// 初始化Serilog日志系统。
    /// 必须在主机构建和依赖注入之前调用，确保所有日志都能被Serilog捕获。
    /// </summary>
    /// <param name="configuration">应用配置对象，通常为builder.Configuration</param>
    public static void Configure(IConfiguration configuration)
    {
        // 读取数据库连接字符串
        var connectionString = configuration.GetConnectionString("Postgres");
        // 读取Serilog相关配置
        var serilogSection = configuration.GetSection("Serilog");
        var minLevel = serilogSection["MinimumLevel"] ?? "Debug";
        var overrideLevel = serilogSection.GetSection("Override")["Microsoft"] ?? "Information";
        var tableName = serilogSection.GetSection("PostgreSQL")["TableName"] ?? "AppLogs";
        var needAutoCreateTable = bool.TryParse(serilogSection.GetSection("PostgreSQL")["NeedAutoCreateTable"], out var autoCreate) ? autoCreate : true;

        // 配置Serilog日志系统，支持控制台和PostgreSQL数据库输出
        Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Is(Enum.TryParse<LogEventLevel>(minLevel, out var lvl) ? lvl : LogEventLevel.Debug)
            .MinimumLevel.Override("Microsoft", Enum.TryParse<LogEventLevel>(overrideLevel, out var olvl) ? olvl : LogEventLevel.Information)
            .Enrich.FromLogContext()
            .WriteTo.Console()
            .WriteTo.PostgreSQL(
                connectionString: connectionString,
                tableName: tableName,
                needAutoCreateTable: needAutoCreateTable,
                columnOptions: new Dictionary<string, ColumnWriterBase>
                {
                    { "Timestamp", new TimestampColumnWriter() },
                    { "Level", new LevelColumnWriter() },
                    { "Message", new RenderedMessageColumnWriter() },
                    { "Exception", new ExceptionColumnWriter() },
                    { "Properties", new LogEventSerializedColumnWriter() },
                    { "LogEvent", new SinglePropertyColumnWriter("LogEvent") }
                })
            .CreateLogger();
    }
} 